package com.ligongmusic.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by wly on 2016/8/24.
 */
public class FlowLayout extends ViewGroup {
    private FlowAdapter adapter;
    /**
     * 存储所有的View，按行记录
     */
    private List<List<View>> mAllViews = new ArrayList<List<View>>();
    /**
     * 记录每一行的最大高度
     */
    private List<Integer> mLineHeight = new ArrayList<Integer>();

    public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FlowLayout(Context context) {
        this(context, null);
    }

    public OnItemClickListener itemClickListener;
    public void setOnItemClickListener(OnItemClickListener listener){
        this.itemClickListener = listener;
    }

    @Override
    protected void onLayout(boolean bool, int l, int t, int r, int b) {
        mAllViews.clear();
        mLineHeight.clear();
        int width = getWidth();
        int lineWidth = 0;
        int lineHeight = 0;
        List<View> views = new ArrayList<View>();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final int position = i;
            View child = getChildAt(i);
            child.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (itemClickListener != null) {
                        // 获取当前条目数量
                        itemClickListener.itemClick(adapter, view, position);
                    }
                }
            });
            LayoutParams p = child.getLayoutParams();
            MarginLayoutParams lp = null;
            if (p instanceof ViewGroup.MarginLayoutParams)
                lp = (MarginLayoutParams) p;
            else
                lp = new ViewGroup.MarginLayoutParams(p);
//            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            int childHeight = child.getMeasuredHeight();
            int childWidth = child.getMeasuredWidth();
            if (childWidth + lp.leftMargin + lp.rightMargin + lineWidth > width) {
                // 换行
                mLineHeight.add(lineHeight);
                // 将当前行的views添加到View集合中
                mAllViews.add(views);
                // 将行宽度置为0
                lineWidth = 0;
                // 清空下一行的子控件集合
                views = new ArrayList<View>();
            }
            // 无需换行，记录当前行宽
            lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
            // 记录行高（取最大高度，控件与之前行高）
            lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
            views.add(child);
        }
        // 循环执行完成，在最后一次不会进入判断是否换行，所以最后一个View只被添加到了LineView中，并没有添加到整个集合，需要在这里添加
        mLineHeight.add(lineHeight);
        mAllViews.add(views);

        int left = 0, top = 0;
        for (int i = 0; i < mAllViews.size(); i++) {
            // 获取行的Views
            views = mAllViews.get(i);
            // 当前行高
            lineHeight = mLineHeight.get(i);
            for (int j = 0; j < views.size(); j++) {
                View view = views.get(j);
                if (view.getVisibility() == View.GONE)
                    continue;
                LayoutParams p = view.getLayoutParams();
                MarginLayoutParams lp = null;
                if (p instanceof ViewGroup.MarginLayoutParams)
                    lp = (MarginLayoutParams) p;
                else
                    lp = new ViewGroup.MarginLayoutParams(p);
//                MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
                int lef = left + lp.leftMargin;
                int right = lef + view.getMeasuredWidth();
                int tp = top + lp.topMargin;
                int bottom = tp + view.getMeasuredHeight();
                view.layout(lef, tp, right, bottom);
                // 记录当前行下一个view的左边位置
                left += lp.leftMargin + lp.rightMargin + view.getMeasuredWidth();
            }
            // 下一行的left位置
            left = 0;
            // 下一行的top位置
            top += lineHeight;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureParent(widthMeasureSpec, heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 添加适配器
     */
    public void setAdapter(FlowAdapter adapter) {
        this.adapter = adapter;
        changeAdapter();
    }


    private void changeAdapter() {
        removeAllViews();
        for (int i = 0; i < adapter.getCount(); i++) {
            addView(adapter.getView(this, i, adapter.getItem(i)));
        }
    }

    /**
     * 测量父控件的高度
     * 如果父控件设置为wrap_content，则要根据子控件显示的行数以及margin属性加上子控件的高度计算
     * 如果父控件设置为精确值，比如固定的dp，或者是fill_parent，则通过模式计算高度
     */
    private void measureParent(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(heightMeasureSpec);
        int parentWidth = 0;
        int parentHeight = 0;
        // 每行的高度
        int lineHeight = 0;
        int lineWidth = 0;
//        int childCount = adapter.getCount();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            // 测量子控件的宽高
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            // 获得子控件的LayoutParams，以便计算子控件实际高度
            LayoutParams p = child.getLayoutParams();
            MarginLayoutParams layoutParams = null;
            if (p instanceof ViewGroup.MarginLayoutParams)
                layoutParams = (MarginLayoutParams) p;
            else
                layoutParams = new ViewGroup.MarginLayoutParams(p);
            int childWidth = child.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin;
            int childHeight = child.getMeasuredHeight() + layoutParams.topMargin + layoutParams.bottomMargin;
            // 如果子控件宽度加上原有宽度超出父控件宽度，则换行
            if (lineWidth + childWidth > widthSize) {
                // 记录当前行宽
                parentWidth = Math.max(lineWidth, childWidth);
                // 记录下一行首个子控件宽度
                lineWidth = childWidth;
                // 记录父控件高度
                parentHeight += lineHeight;
                // 记录下一行高度
                lineHeight = childHeight;
            } else {
                lineWidth += childWidth;
                // 记录行最大高度
                lineHeight = Math.max(lineHeight, childHeight);
            }
            // 如果是最后一个，则将当前记录的最大宽度和当前lineWidth做比较
            if (i == childCount - 1) {
                parentHeight += lineHeight;
                parentWidth = Math.max(parentWidth, lineWidth);
            }
        }
        // 如果设置非精确值，则将计算的宽度设置给父控件

        if (widthMode != MeasureSpec.EXACTLY) {
            if (widthMode == MeasureSpec.AT_MOST)
                widthSize = Math.min(widthSize, parentWidth);
            else
                widthSize = parentWidth;
        }

        Log.e("LoggerUtils", "宽：" + widthSize + "");

        if (heightMode != MeasureSpec.EXACTLY)
            heightSize = parentHeight;

        setMeasuredDimension(widthSize, heightSize);

    }

    /**
     * 使控件支持margin属性
     */
    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    public interface OnItemClickListener{
        void itemClick(FlowAdapter adapter, View view, int position);
    }

}